<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>五子棋 - 现代木纹版</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
          rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#8B5A2B',
                        secondary: '#D2B48C',
                        accent: '#CD853F',
                        board: '#DEB887',
                        boardDark: '#C19A6B',
                        blackPiece: '#2D2D2D',
                        whitePiece: '#F5F5F5',
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .wood-pattern {
                background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23a67c52' fill-opacity='0.2' fill-rule='evenodd'/%3E%3C/svg%3E");
            }
            .piece-transition {
                transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
            }
            .pulse-effect {
                animation: pulse 1.5s infinite;
            }
            @keyframes pulse {
                0% { transform: scale(1); }
                50% { transform: scale(1.05); }
                100% { transform: scale(1); }
            }
            .fade-in {
                animation: fadeIn 0.5s ease forwards;
            }
            @keyframes fadeIn {
                from { opacity: 0; }
                to { opacity: 1; }
            }
            .scale-in {
                animation: scaleIn 0.3s ease forwards;
            }
            @keyframes scaleIn {
                from { transform: scale(0.8); opacity: 0; }
                to { transform: scale(1); opacity: 1; }
            }
        }
    </style>
</head>
<body class="bg-gray-100 min-h-screen flex flex-col items-center justify-center p-4 font-sans">
<div class="max-w-5xl w-full bg-white rounded-2xl shadow-xl overflow-hidden transform transition-all duration-300 hover:shadow-2xl">
    <!-- 游戏标题区域 -->
    <div class="bg-primary wood-pattern text-white p-2 text-center relative overflow-hidden">
        <div class="absolute inset-0 bg-primary/70"></div>
        <div class="relative z-10">
            <h1 class="text-[clamp(1.8rem,4vw,3rem)] font-bold tracking-wide">五子棋</h1>
            <p class="text-secondary mt-1 text-lg">经典对弈 · 智者的游戏</p>
        </div>
    </div>

    <!-- 主要游戏区域 -->
    <div class="p-4 md:p-8 flex flex-col lg:flex-row gap-6 lg:gap-8">
        <!-- 棋盘区域 -->
        <div class="flex-1 flex flex-col items-center">
            <div class="relative">
                <!-- 木纹棋盘背景 -->
                <div class="absolute inset-0 rounded-lg wood-pattern bg-board shadow-xl"></div>
                <!-- 棋盘网格覆盖层 -->
                <div class="relative aspect-square w-full max-w-md border-8 border-boardDark rounded-lg shadow-inner overflow-hidden"
                     style="background-size: calc(100% / 14) calc(100% / 14);
                                background-image: linear-gradient(to right, rgba(0,0,0,0.3) 1px, transparent 1px),
                                                  linear-gradient(to bottom, rgba(0,0,0,0.3) 1px, transparent 1px);">
                    <canvas id="gameCanvas" class="w-full h-full cursor-pointer"></canvas>
                </div>
            </div>

            <!-- 游戏状态提示 -->
            <div class="mt-4 w-full max-w-md p-1 bg-secondary/20 rounded-lg border border-secondary/30 text-center">
                <p id="statusText" class="font-medium text-lg text-gray-800">游戏开始! 黑棋先行</p>
            </div>
        </div>

        <!-- 游戏信息和控制区域 -->
        <div class="w-full lg:w-80 flex flex-col gap-4">
            <!-- 控制按钮 -->
            <div class="flex flex-col gap-3">
                <button id="restartBtn"
                        class="w-full bg-primary hover:bg-primary/90 text-white py-2 px-4 rounded-lg font-medium shadow-md transition-all duration-200 flex items-center justify-center">
                    <i class="fa-solid fa-refresh mr-2"></i>重新开始
                </button>
                <button id="undoBtn"
                        class="w-full bg-secondary hover:bg-secondary/90 text-gray-800 py-2 px-4 rounded-lg font-medium shadow-md transition-all duration-200 flex items-center justify-center">
                    <i class="fa-solid fa-undo mr-2"></i>悔棋
                </button>
            </div>

            <!-- 游戏信息卡片 -->
            <div class="bg-white rounded-xl shadow-md p-3 border border-gray-100">
                <h2 class="text-lg font-semibold mb-4 flex items-center text-primary">
                    <i class="fa-solid fa-info-circle mr-2"></i>游戏信息
                </h2>
                <div class="space-y-4">
                    <!-- 当前玩家 -->
                    <div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
                        <span class="text-gray-600">当前回合</span>
                        <div class="flex items-center">
                            <div id="currentPlayer"
                                 class="w-6 h-6 rounded-full bg-blackPiece mr-2 shadow-md"></div>
                            <span id="playerText" class="font-medium">黑棋</span>
                        </div>
                    </div>

                    <!-- 游戏时间 -->
                    <div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
                        <span class="text-gray-600">游戏时间</span>
                        <span id="gameTime" class="font-mono font-medium">00:00</span>
                    </div>

                    <!-- 已走步数 -->
                    <div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
                        <span class="text-gray-600">已走步数</span>
                        <span id="moveCount" class="font-medium">0</span>
                    </div>
                </div>
            </div>

            <!-- 游戏规则卡片 -->
            <div class="bg-white rounded-xl shadow-md p-3 border border-gray-100">
                <h2 class="text-lg font-semibold mb-4 flex items-center text-primary">
                    <i class="fa-solid fa-book-open mr-2"></i>游戏规则
                </h2>
                <ul class="text-sm text-gray-600 space-y-2">
                    <li class="flex items-start">
                        <i class="fa-solid fa-circle text-xs mt-1.5 mr-2 text-accent"></i>
                        <span>黑白双方轮流在棋盘交叉点落子</span>
                    </li>
                    <li class="flex items-start">
                        <i class="fa-solid fa-circle text-xs mt-1.5 mr-2 text-accent"></i>
                        <span>先在横、竖或斜方向连成五子者获胜</span>
                    </li>
                    <li class="flex items-start">
                        <i class="fa-solid fa-circle text-xs mt-1.5 mr-2 text-accent"></i>
                        <span>棋盘下满仍无人获胜则判定为平局</span>
                    </li>
                </ul>
            </div>

        </div>
    </div>

    <!-- 页脚 -->
    <div class="bg-gray-50 p-4 text-center text-sm text-gray-500 border-t border-gray-100">
        <p>© 2025 五子棋 · 现代木纹版</p>
    </div>
</div>

<!-- 胜利提示模态框 -->
<div id="winModal"
     class="fixed inset-0 bg-black/60 flex items-center justify-center z-50 hidden opacity-0 transition-opacity duration-300">
    <div class="bg-white rounded-2xl p-8 max-w-md w-full mx-4 transform transition-transform duration-300 scale-95 shadow-2xl">
        <div class="text-center">
            <div class="w-20 h-20 bg-yellow-100 rounded-full flex items-center justify-center mx-auto mb-6 pulse-effect">
                <i class="fa-solid fa-trophy text-4xl text-yellow-500"></i>
            </div>
            <h2 class="text-2xl font-bold mb-3" id="winnerText">黑棋获胜!</h2>
            <p class="text-gray-600 mb-8" id="winMessage">恭喜您赢得了这场精彩的比赛!</p>
            <button id="newGameBtn"
                    class="bg-primary hover:bg-primary/90 text-white py-3 px-8 rounded-lg font-medium shadow-md transition-all duration-200 w-full">
                开始新游戏
            </button>
        </div>
    </div>
</div>

<!-- 平局提示模态框 -->
<div id="drawModal"
     class="fixed inset-0 bg-black/60 flex items-center justify-center z-50 hidden opacity-0 transition-opacity duration-300">
    <div class="bg-white rounded-2xl p-8 max-w-md w-full mx-4 transform transition-transform duration-300 scale-95 shadow-2xl">
        <div class="text-center">
            <div class="w-20 h-20 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-6">
                <i class="fa-solid fa-handshake text-4xl text-blue-500"></i>
            </div>
            <h2 class="text-2xl font-bold mb-3">平局!</h2>
            <p class="text-gray-600 mb-8">棋盘已下满，双方势均力敌!</p>
            <button id="newDrawGameBtn"
                    class="bg-primary hover:bg-primary/90 text-white py-3 px-8 rounded-lg font-medium shadow-md transition-all duration-200 w-full">
                开始新游戏
            </button>
        </div>
    </div>
</div>

<script>
    document.addEventListener('DOMContentLoaded', () => {
        // 游戏常量
        const BOARD_SIZE = 15; // 15x15的棋盘
        // 根据屏幕尺寸动态计算单元格大小
        const getCellSize = () => {
            const maxWidth = window.innerWidth < 768 ? window.innerWidth * 0.9 : 500;
            return Math.floor(maxWidth / (BOARD_SIZE - 1));
        };
        let CELL_SIZE = getCellSize();
        const PIECE_SIZE_RATIO = 0.85; // 棋子大小与单元格的比例

        // 游戏状态
        let gameBoard = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(0));
        let currentPlayer = 1; // 1: 黑棋, 2: 白棋
        let gameActive = true;
        let moveHistory = [];
        let gameTime = 0;
        let timerInterval;
        let mousePos = { x: -1, y: -1 }; // 记录鼠标位置用于预览

        // DOM元素
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const statusText = document.getElementById('statusText');
        const currentPlayerEl = document.getElementById('currentPlayer');
        const playerText = document.getElementById('playerText');
        const moveCountEl = document.getElementById('moveCount');
        const gameTimeEl = document.getElementById('gameTime');
        const restartBtn = document.getElementById('restartBtn');
        const undoBtn = document.getElementById('undoBtn');
        const winModal = document.getElementById('winModal');
        const winnerText = document.getElementById('winnerText');
        const winMessage = document.getElementById('winMessage');
        const newGameBtn = document.getElementById('newGameBtn');
        const drawModal = document.getElementById('drawModal');
        const newDrawGameBtn = document.getElementById('newDrawGameBtn');

        // 设置Canvas尺寸
        function resizeCanvas() {
            CELL_SIZE = getCellSize();
            canvas.width = CELL_SIZE * (BOARD_SIZE - 1);
            canvas.height = CELL_SIZE * (BOARD_SIZE - 1);
            drawBoard();
        }

        // 初始化时调整一次尺寸，并监听窗口大小变化
        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);

        // 绘制棋盘
        function drawBoard() {
            // 清除画布
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // 绘制天元和星位
            const starPoints = [
                {x: 3, y: 3}, {x: 3, y: 11}, {x: 7, y: 7},
                {x: 11, y: 3}, {x: 11, y: 11}
            ];

            starPoints.forEach(point => {
                ctx.beginPath();
                ctx.arc(point.x * CELL_SIZE, point.y * CELL_SIZE, 3, 0, Math.PI * 2);
                ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
                ctx.fill();
            });

            // 绘制棋子
            drawPieces();

            // 绘制鼠标悬停预览
            drawMousePreview();
        }

        // 绘制所有棋子
        function drawPieces() {
            for (let i = 0; i < BOARD_SIZE; i++) {
                for (let j = 0; j < BOARD_SIZE; j++) {
                    if (gameBoard[i][j] !== 0) {
                        drawPiece(i, j, gameBoard[i][j]);
                    }
                }
            }
        }

        // 绘制单个棋子
        function drawPiece(row, col, player, isPreview = false) {
            const x = col * CELL_SIZE;
            const y = row * CELL_SIZE;
            const pieceSize = CELL_SIZE * PIECE_SIZE_RATIO;
            const alpha = isPreview ? 0.5 : 1;

            // 棋子阴影
            ctx.beginPath();
            ctx.arc(x, y, pieceSize / 2, 0, Math.PI * 2);
            ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
            ctx.shadowBlur = 6;
            ctx.shadowOffsetX = 0;
            ctx.shadowOffsetY = 3;

            if (player === 1) {
                // 黑棋 - 带渐变效果
                const gradient = ctx.createRadialGradient(
                    x - pieceSize / 8, y - pieceSize / 8, pieceSize / 10,
                    x, y, pieceSize / 2
                );
                gradient.addColorStop(0, '#555555');
                gradient.addColorStop(1, '#000000');
                ctx.fillStyle = gradient;
            } else {
                // 白棋 - 带渐变效果
                const gradient = ctx.createRadialGradient(
                    x - pieceSize / 8, y - pieceSize / 8, pieceSize / 10,
                    x, y, pieceSize / 2
                );
                gradient.addColorStop(0, '#FFFFFF');
                gradient.addColorStop(1, '#DDDDDD');
                ctx.fillStyle = gradient;
            }

            ctx.globalAlpha = alpha;
            ctx.fill();
            ctx.shadowBlur = 0; // 重置阴影

            // 棋子边缘
            ctx.beginPath();
            ctx.arc(x, y, pieceSize / 2, 0, Math.PI * 2);
            ctx.strokeStyle = player === 1 ? '#333333' : '#CCCCCC';
            ctx.lineWidth = 1;
            ctx.stroke();

            // 重置透明度
            ctx.globalAlpha = 1;
        }

        // 绘制鼠标悬停预览
        function drawMousePreview() {
            if (!gameActive || mousePos.x === -1 || mousePos.y === -1) return;

            const rect = canvas.getBoundingClientRect();
            const scaleX = canvas.width / rect.width;
            const scaleY = canvas.height / rect.height;

            // 计算鼠标在画布上的位置
            const canvasX = (mousePos.x - rect.left) * scaleX;
            const canvasY = (mousePos.y - rect.top) * scaleY;

            // 计算最近的交叉点
            const col = Math.round(canvasX / CELL_SIZE);
            const row = Math.round(canvasY / CELL_SIZE);

            // 检查是否在棋盘内且为空位
            if (row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE && gameBoard[row][col] === 0) {
                // 绘制预览棋子
                drawPiece(row, col, currentPlayer, true);
            }
        }

        // 检查胜利条件
        function checkWin(row, col, player) {
            const directions = [
                [1, 0],   // 水平
                [0, 1],   // 垂直
                [1, 1],   // 对角线
                [1, -1]   // 反对角线
            ];

            for (const [dx, dy] of directions) {
                let count = 1;  // 当前位置已经有一个棋子

                // 正向检查
                for (let i = 1; i < 5; i++) {
                    const newRow = row + i * dy;
                    const newCol = col + i * dx;

                    if (newRow < 0 || newRow >= BOARD_SIZE || newCol < 0 || newCol >= BOARD_SIZE) {
                        break;
                    }

                    if (gameBoard[newRow][newCol] === player) {
                        count++;
                    } else {
                        break;
                    }
                }

                // 反向检查
                for (let i = 1; i < 5; i++) {
                    const newRow = row - i * dy;
                    const newCol = col - i * dx;

                    if (newRow < 0 || newRow >= BOARD_SIZE || newCol < 0 || newCol >= BOARD_SIZE) {
                        break;
                    }

                    if (gameBoard[newRow][newCol] === player) {
                        count++;
                    } else {
                        break;
                    }
                }

                if (count >= 5) {
                    // 高亮显示获胜的五个棋子
                    highlightWinningPieces(row, col, dx, dy, player);
                    return true;
                }
            }

            return false;
        }

        // 高亮显示获胜的棋子
        function highlightWinningPieces(row, col, dx, dy, player) {
            // 收集获胜的五个棋子位置
            const winningPieces = [{row, col}];

            // 正向查找
            for (let i = 1; i < 5; i++) {
                const newRow = row + i * dy;
                const newCol = col + i * dx;
                if (newRow >= 0 && newRow < BOARD_SIZE && newCol >= 0 && newCol < BOARD_SIZE &&
                    gameBoard[newRow][newCol] === player) {
                    winningPieces.push({row: newRow, col: newCol});
                } else {
                    break;
                }
            }

            // 反向查找
            for (let i = 1; i < 5; i++) {
                const newRow = row - i * dy;
                const newCol = col - i * dx;
                if (newRow >= 0 && newRow < BOARD_SIZE && newCol >= 0 && newCol < BOARD_SIZE &&
                    gameBoard[newRow][newCol] === player) {
                    winningPieces.push({row: newRow, col: newCol});
                } else {
                    break;
                }
            }

            // 只保留五个连续的棋子
            const finalWinningPieces = winningPieces.slice(0, 5);

            // 绘制高亮效果
            setTimeout(() => {
                finalWinningPieces.forEach(piece => {
                    const x = piece.col * CELL_SIZE;
                    const y = piece.row * CELL_SIZE;
                    const pieceSize = CELL_SIZE * PIECE_SIZE_RATIO;

                    ctx.beginPath();
                    ctx.arc(x, y, pieceSize / 2 + 4, 0, Math.PI * 2);
                    ctx.strokeStyle = '#F6AD55';
                    ctx.lineWidth = 3;
                    ctx.stroke();
                });
            }, 100);
        }

        // 检查平局
        function checkDraw() {
            for (let i = 0; i < BOARD_SIZE; i++) {
                for (let j = 0; j < BOARD_SIZE; j++) {
                    if (gameBoard[i][j] === 0) {
                        return false; // 还有空位，不是平局
                    }
                }
            }
            return true; // 棋盘已满，平局
        }

        // 更新游戏状态显示
        function updateGameStatus() {
            if (gameActive) {
                statusText.textContent = `游戏进行中 - ${currentPlayer === 1 ? '黑棋' : '白棋'}回合`;
                currentPlayerEl.className = `w-6 h-6 rounded-full ${currentPlayer === 1 ? 'bg-blackPiece' : 'bg-whitePiece border border-gray-300'} mr-2 shadow-md`;
                playerText.textContent = currentPlayer === 1 ? '黑棋' : '白棋';
            }
            moveCountEl.textContent = moveHistory.length;
        }

        // 更新游戏时间
        function updateGameTime() {
            gameTime++;
            const minutes = Math.floor(gameTime / 60).toString().padStart(2, '0');
            const seconds = (gameTime % 60).toString().padStart(2, '0');
            gameTimeEl.textContent = `${minutes}:${seconds}`;
        }

        // 开始计时
        function startTimer() {
            clearInterval(timerInterval);
            timerInterval = setInterval(updateGameTime, 1000);
        }

        // 停止计时
        function stopTimer() {
            clearInterval(timerInterval);
        }

        // 显示胜利模态框
        function showWinModal(winner) {
            gameActive = false;
            stopTimer();

            winnerText.textContent = `${winner === 1 ? '黑棋' : '白棋'}获胜!`;
            winMessage.textContent = `恭喜您在 ${moveHistory.length} 步后赢得了比赛!`;

            // 显示模态框并添加动画
            winModal.classList.remove('hidden');
            setTimeout(() => {
                winModal.classList.add('opacity-100');
                winModal.querySelector('div').classList.remove('scale-95');
                winModal.querySelector('div').classList.add('scale-100');
            }, 10);
        }

        // 显示平局模态框
        function showDrawModal() {
            gameActive = false;
            stopTimer();

            // 显示模态框并添加动画
            drawModal.classList.remove('hidden');
            setTimeout(() => {
                drawModal.classList.add('opacity-100');
                drawModal.querySelector('div').classList.remove('scale-95');
                drawModal.querySelector('div').classList.add('scale-100');
            }, 10);
        }

        // 隐藏模态框
        function hideModals() {
            // 隐藏胜利模态框
            winModal.classList.remove('opacity-100');
            winModal.querySelector('div').classList.remove('scale-100');
            winModal.querySelector('div').classList.add('scale-95');

            // 隐藏平局模态框
            drawModal.classList.remove('opacity-100');
            drawModal.querySelector('div').classList.remove('scale-100');
            drawModal.querySelector('div').classList.add('scale-95');

            setTimeout(() => {
                winModal.classList.add('hidden');
                drawModal.classList.add('hidden');
            }, 300);
        }

        // 重置游戏
        function resetGame() {
            gameBoard = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(0));
            currentPlayer = 1;
            gameActive = true;
            moveHistory = [];
            gameTime = 0;

            drawBoard();
            updateGameStatus();
            gameTimeEl.textContent = '00:00';

            stopTimer();
            startTimer();

            hideModals();
        }

        // 悔棋
        function undoMove() {
            if (moveHistory.length === 0 || !gameActive) {
                return;
            }

            const lastMove = moveHistory.pop();
            gameBoard[lastMove.row][lastMove.col] = 0;
            currentPlayer = lastMove.player; // 回到上一个玩家

            drawBoard();
            updateGameStatus();
        }

        // 处理棋盘点击
        function handleBoardClick(e) {
            if (!gameActive) return;

            const rect = canvas.getBoundingClientRect();
            const scaleX = canvas.width / rect.width;
            const scaleY = canvas.height / rect.height;

            // 计算点击的坐标
            const x = (e.clientX - rect.left) * scaleX;
            const y = (e.clientY - rect.top) * scaleY;

            // 计算最近的交叉点
            const col = Math.round(x / CELL_SIZE);
            const row = Math.round(y / CELL_SIZE);

            // 检查坐标是否在棋盘内且为空位
            if (row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE && gameBoard[row][col] === 0) {
                // 记录历史
                moveHistory.push({row, col, player: currentPlayer});

                // 落子
                gameBoard[row][col] = currentPlayer;

                // 添加落子动画效果
                const pieceSize = CELL_SIZE * PIECE_SIZE_RATIO;
                const xPos = col * CELL_SIZE;
                const yPos = row * CELL_SIZE;

                // 绘制缩小的棋子
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                drawPieces();
                ctx.beginPath();
                ctx.arc(xPos, yPos, pieceSize / 4, 0, Math.PI * 2);
                ctx.fillStyle = currentPlayer === 1 ? '#000' : '#fff';
                ctx.fill();

                // 动画放大到正常大小
                setTimeout(() => {
                    drawBoard();

                    // 检查是否胜利
                    if (checkWin(row, col, currentPlayer)) {
                        showWinModal(currentPlayer);
                        return;
                    }

                    // 检查是否平局
                    if (checkDraw()) {
                        showDrawModal();
                        return;
                    }

                    // 切换玩家
                    currentPlayer = currentPlayer === 1 ? 2 : 1;
                    updateGameStatus();
                }, 100);
            }
        }

        // 事件监听
        canvas.addEventListener('click', handleBoardClick);

        // 鼠标移动事件 - 用于预览
        canvas.addEventListener('mousemove', (e) => {
            mousePos.x = e.clientX;
            mousePos.y = e.clientY;
            if (gameActive) {
                drawBoard();
            }
        });

        // 鼠标离开棋盘时清除预览
        canvas.addEventListener('mouseleave', () => {
            mousePos.x = -1;
            mousePos.y = -1;
            drawBoard();
        });

        // 控制按钮事件
        restartBtn.addEventListener('click', resetGame);
        undoBtn.addEventListener('click', undoMove);
        newGameBtn.addEventListener('click', resetGame);
        newDrawGameBtn.addEventListener('click', resetGame);

        // 初始化游戏
        drawBoard();
        updateGameStatus();
        startTimer();
    });
</script>
</body>
</html>
    